package com.danbay.cloud.device.service;

import com.danbay.cloud.base.constants.Const;
import com.danbay.cloud.device.api.dto.DeviceInfoDto;
import com.danbay.cloud.device.api.dto.DeviceRegDto;
import com.danbay.cloud.device.dto.DeviceOfflineListDto;
import com.danbay.framework.redis.RedisClient;
import com.danbay.framework.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * @author SJG
 *         2017/10/20
 *         设备信息缓存
 */
@Service
public class DeviceCacheService {

    private RedisClient redisClient;

    @Autowired
    public DeviceCacheService(RedisClient redisClient) {
        this.redisClient = redisClient;
    }

    /**
     * 设备的hash key
     *
     * @param dev_id 设备id
     * @return
     */
    public String getDevHashKey(String dev_id) {
        Objects.requireNonNull(dev_id);
        return "device:" + dev_id;
    }

    /**
     * 设备注册时获取注册key
     *
     * @param regDto
     * @return
     */
    public String getDevRegKey(DeviceRegDto regDto) {
        return "dev_reg:" + regDto.getMac();
    }

    /**
     * 将设备信息注册到redis
     *
     * @param regInfo 注册信息
     * @param devId   注册成功后生成的设备id
     */
    public void cacheRegInfo(DeviceRegDto regInfo, String devId) {
        String devHashKey = getDevHashKey(devId);
        //设备新注册；
        redisClient.hset(devHashKey, "device_no", devId);
        redisClient.hset(devHashKey, "sn_id", regInfo.getSn());
        redisClient.hset(devHashKey, "mac_address", regInfo.getMac());
        redisClient.hset(devHashKey, "register_time", DateUtils.now(DateUtils.YMDHMS1));
        redisClient.hset(devHashKey, "register_ip", regInfo.getIp());
        //关联中控设备id
        redisClient.hset(devHashKey, "ctrlDevId", regInfo.getFatherDevId());

        //缓存注册标识
        redisClient.set(getDevRegKey(regInfo), devId);
    }

    /**
     * 更新设备注册信息
     *
     * @param deviceInfo 设备信息
     */
    public void updateRegDeviceInfo(DeviceInfoDto deviceInfo) {
        String devHashKey = getDevHashKey(deviceInfo.getDevId());
        if (deviceInfo.getIp() != null) {
            redisClient.hset(devHashKey, "register_ip", deviceInfo.getIp());
        }
    }

    /**
     * 取缓存的设备注册信息
     *
     * @param devId 设备id
     * @return
     */
    public DeviceInfoDto getDeviceInfo(String devId) {
        String devHashKey = getDevHashKey(devId);
        if (!redisClient.hasKey(devHashKey)) {
            return null;
        }

        DeviceInfoDto deviceInfo = new DeviceInfoDto();
        deviceInfo.setDevId(redisClient.hget(devHashKey, "device_no").toString());
        deviceInfo.setName(redisClient.hget(devHashKey, "sn_id").toString());
        deviceInfo.setMac(redisClient.hget(devHashKey, "mac_address").toString());
        deviceInfo.setIp(redisClient.hget(devHashKey, "register_ip").toString());
        Object ctrlDevId = redisClient.hget(devHashKey, "ctrlDevId");
        deviceInfo.setCtrlDevId(ctrlDevId == null ? "" : ctrlDevId.toString());
        return deviceInfo;
    }

    /**
     * 设备是否已注册返回devId
     *
     * @param regDto 注册信息
     * @return devId
     */
    public String getRegisteredDevId(DeviceRegDto regDto) {
        String regKey = getDevRegKey(regDto);
        return redisClient.get(regKey);
    }

    /**
     * 设备是否已注册
     *
     * @param regDto 注册信息
     * @return
     */
    public boolean isRegistered(DeviceRegDto regDto) {
        String regKey = getDevRegKey(regDto);
        return redisClient.hasKey(regKey);
    }

    /**
     * 设备是否已注册
     *
     * @param devId 设备id
     * @return
     */
    public boolean isRegistered(String devId) {
        String devHashKey = getDevHashKey(devId);
        return redisClient.hasKey(devHashKey);
    }

    /**
     * 设置设备离线
     *
     * @param deviceID 设备ID
     * @return
     */
    public void setDeviceOffline(String deviceID) {
        redisClient.del(getDeviceOnlineKey(deviceID));
    }

    /**
     * 设备设备在线
     *
     * @param deviceID 设备ID
     * @return
     */
    public void setDeviceOnline(String deviceID, String serviceIPAndPort) {
        redisClient.set(getDeviceOnlineKey(deviceID), serviceIPAndPort);
    }

    public void setDeviceOfflineList(String key, DeviceOfflineListDto deviceOfflineListDto){
        redisClient.setEntity(key,deviceOfflineListDto);
    }

    public DeviceOfflineListDto getDeviceOfflineList(String key) {
        return isDeviceOffLineExist(key) ? redisClient.getEntity(key) : new DeviceOfflineListDto();
    }

    private boolean isDeviceOffLineExist(String key) {
        return redisClient.hasKey(key);
    }

    /**
     * 得到设备的在线状态
     *
     * @param deviceID 设备ID
     * @return true表示在线，false表示离线
     */
    public boolean isDeviceOnline(String deviceID) {
        return redisClient.hasKey(getDeviceOnlineKey(deviceID));
    }


    private String getDeviceOnlineKey(String deviceID) {
        return Const.DEVICE_ONLINE_KEY + deviceID;
    }


}
